package com.zjhn.ds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zjhn.ds.common.BizResult;
import com.zjhn.ds.common.PageResult;
import com.zjhn.ds.domain.dto.pc.GroupDto;
import com.zjhn.ds.domain.dto.pc.SpinnerDto;
import com.zjhn.ds.domain.dto.pc.WorkShopStationDto;
import com.zjhn.ds.domain.entity.jlw.*;
import com.zjhn.ds.domain.vo.OperatorVo;
import com.zjhn.ds.mapper.*;
import com.zjhn.ds.param.*;
import com.zjhn.ds.service.GroupService;
import com.zjhn.ds.service.GroupSpinnerService;
import com.zjhn.ds.service.GroupStationService;
import com.zjhn.ds.utils.CommonUtil;
import com.zjhn.ds.utils.base.DateUtil;
import com.zjhn.ds.utils.EntityTransformUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @BelongsProject: ds_jlw
 * @BelongsPackage: com.zjhn.ds.service.impl
 * @Author: sxt
 * @CreateTime: 2023-09-11  10:17
 * @Description:
 * @Version: 1.0
 */
@Slf4j
@Service
public class GroupServiceImpl implements GroupService {

    @Resource
    private CommonUtil commonUtil;

    @Resource
    private EntityTransformUtil entityTransformUtil;

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private GroupSpinnerService groupSpinnerService;

    @Resource
    private GroupStationService groupStationService;

    @Resource
    private SpinnerMapper spinnerMapper;

    @Resource
    private StationMapper stationMapper;


    /**
     * 新增车间小组
     * @param param
     * @return
     */
    @Override
    public BizResult<?> addUpdateGroup(AddGroupParam param) {
        if(StringUtils.isNotBlank(param.getGroupId())) {
            // 更新
            Group group = groupMapper.selectById(param.getGroupId());
            if (group == null)
                return BizResult.fail("分组不存在");
            Group same = groupMapper.selectOne(
                    new QueryWrapper<Group>().ne("id",group.getId()).eq("group_name", param.getGroupName()));
            if (same != null)
                return BizResult.fail("分组名称已存在");

            group.setGroupName(param.getGroupName());
            group.setWorkshopId(param.getWorkshopId());
            groupMapper.updateById(group);
        }else {
            // 新增
            Group group = groupMapper.selectOne(new QueryWrapper<Group>().eq("group_name", param.getGroupName()));
            if (group != null)
                return BizResult.fail("分组名称已存在");

            group = Group.builder()
                    .groupName(param.getGroupName())
                    .workshopId(param.getWorkshopId())
                    .build();
            groupMapper.insert(group);
        }

        return BizResult.success();
    }

    /**
     * 删除车间小组
     * @param groupId
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> removeGroup(String groupId) {
        Group group = groupMapper.selectById(groupId);
        if (group == null)
            return BizResult.success();

        groupSpinnerService.remove(new QueryWrapper<GroupSpinner>().eq("group_id", groupId));
        groupStationService.remove(new QueryWrapper<GroupStation>().eq("group_id", groupId));
        groupMapper.deleteById(groupId);

        return BizResult.success();
    }

    /**
     * 按条件分页查询车间小组
     * @param param
     * @return
     */
    @Override
    public BizResult<PageResult<GroupDto>> groupPage(GroupPageParam param) {
        QueryWrapper<Group> queryWrapper = new QueryWrapper<Group>();
        if (StringUtils.isNotBlank(param.getWorkshopId()))
            queryWrapper.eq("workshop_id", param.getWorkshopId());
        if (StringUtils.isNotBlank(param.getGroupName()))
            queryWrapper.like("group_name", param.getGroupName());
        IPage<Group> page = groupMapper.selectPage(
                new Page<>(param.getCurrent(), param.getSize()),
                queryWrapper.orderByAsc("group_name")
        );

        IPage<GroupDto> convert = page.convert(c -> GroupDto.builder()
                .groupId(c.getId())
                .groupName(c.getGroupName())
                .workshopId(c.getWorkshopId())
                .workshop(commonUtil.getWorkshopById(c.getWorkshopId()))
                .creatTime(DateUtil.formatDateToString(c.getCreateTime()))
                .build());

        return BizResult.success(PageResult.<GroupDto>builder()
                .current(convert.getCurrent())
                .pages(convert.getPages())
                .size(convert.getSize())
                .record(convert.getRecords())
                .build());
    }

    /**
     * 分页查询车间小组挡车工
     * @param param
     * @return
     */
    @Override
    public BizResult<PageResult<SpinnerDto>> spinnerPage(GroupRelParam param) {
        List<GroupSpinner> groupSpinners = groupSpinnerService.list(new QueryWrapper<GroupSpinner>().eq("group_id", param.getGroupId()));
        if (groupSpinners.size() == 0)
            return BizResult.success(PageResult.<SpinnerDto>builder().build());

        Set<String> spinnerIds = groupSpinners.stream().map(GroupSpinner::getSpinnerId).collect(Collectors.toSet());
        IPage<Spinner> page = spinnerMapper.selectPage(
                new Page<>(param.getCurrent(), param.getSize()),
                new QueryWrapper<Spinner>().in("id",spinnerIds));
        IPage<SpinnerDto> convert = page.convert(c -> {
            OperatorVo operator = commonUtil.getOperatorById(c.getOperateId());
            return SpinnerDto.builder()
                    .spinnerId(c.getId())
                    .username(operator.getUsername())
                    .userNo(operator.getUserNo())
                    .realName(operator.getRealName())
                    .department(commonUtil.getDepartmentId(operator.getDepartmentGuid()))
                    .createTime(DateUtil.formatDateToString(c.getCreateTime()))
                    .build();
        });

        return BizResult.success(PageResult.<SpinnerDto>builder()
                .current(convert.getCurrent())
                .pages(convert.getPages())
                .size(convert.getSize())
                .record(convert.getRecords())
                .build());
    }

    /**
     * 分页查询车间小组工位信息
     * @param param
     * @return
     */
    @Override
    public BizResult<PageResult<WorkShopStationDto>> stationPage(GroupRelParam param) {
        List<GroupStation> groupStations = groupStationService.list(new QueryWrapper<GroupStation>().eq("group_id", param.getGroupId()));
        List<String> stationIds = groupStations.stream().map(GroupStation::getStationId).collect(Collectors.toList());
        if (stationIds.size() == 0)
            return BizResult.success(PageResult.<WorkShopStationDto>builder().build());

        IPage<Station> page = stationMapper.selectPage(
                new Page<>(param.getCurrent(), param.getSize()),
                new QueryWrapper<Station>().in("id",stationIds)
                        .orderByAsc("line_number","column_number","station_code")
        );
        IPage<WorkShopStationDto> convert = entityTransformUtil.workshopStationDtoChange(page);

        return BizResult.success(PageResult.<WorkShopStationDto>builder()
                .current(convert.getCurrent())
                .pages(convert.getPages())
                .size(convert.getSize())
                .record(convert.getRecords())
                .build());
    }

    /**
     * 车间小组批量绑定挡车工或工位
     * @param param
     * @return
     */
    @Transactional
    @Override
    public BizResult<?> groupBind(GroupBindParam param){
        Group group = groupMapper.selectById(param.getGroupId());
        if (group == null)
            return BizResult.fail("分组不存在");

        if (param.getSpinnerId() != null && param.getSpinnerId().size() > 0) {
            int count = groupSpinnerService.count(new QueryWrapper<GroupSpinner>().in("spinner_id", param.getSpinnerId()));
            if (count > 0)
                return BizResult.fail("挡车工已在其他组内");

            List<GroupSpinner> collect = param.getSpinnerId().stream()
                    .map(c -> GroupSpinner.builder()
                            .groupId(param.getGroupId())
                            .spinnerId(c)
                            .build())
                    .collect(Collectors.toList());
            groupSpinnerService.saveBatch(collect);
        }
        if (param.getStationId() != null && param.getStationId().size() > 0) {
            int count = groupStationService.count(new QueryWrapper<GroupStation>().in("station_id", param.getStationId()));
            if (count > 0)
                return BizResult.fail("工位已在其他组内");

            List<GroupStation> collect = param.getStationId().stream()
                    .map(c -> GroupStation.builder()
                            .groupId(param.getGroupId())
                            .stationId(c)
                            .build())
                    .collect(Collectors.toList());
            groupStationService.saveBatch(collect);
        }

        return BizResult.success();
    }

    /**
     * 车间小组解绑挡车工或工位
     * @param param
     * @return
     */
    @Override
    public BizResult<?> groupUnBind(GroupUnBindParam param) {
        Group group = groupMapper.selectById(param.getGroupId());
        if (group == null)
            return BizResult.fail("分组不存在");

        if (StringUtils.isNotBlank(param.getSpinnerId())) {
            GroupSpinner groupSpinner = groupSpinnerService.getOne(
                    new QueryWrapper<GroupSpinner>()
                            .eq("group_id", param.getGroupId()).eq("spinner_id", param.getSpinnerId()));
            if (groupSpinner != null)
                groupSpinnerService.removeById(groupSpinner.getId());
        }
        if (StringUtils.isNotBlank(param.getStationId())) {
            GroupStation groupStation = groupStationService.getOne(
                    new QueryWrapper<GroupStation>()
                            .eq("group_id", param.getGroupId()).eq("station_id", param.getStationId()));
            if (groupStation != null)
                groupStationService.removeById(groupStation.getId());
        }

        return BizResult.success();
    }

}
